package ar.edu.unrn.lia.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "propiedad")
public class Propiedad extends BaseEntity implements Serializable {

	private static final long serialVersionUID = 6793646897385223222L;

	private Coordenada coordenada = new Coordenada();

	private Propietario propietario;

	private Barrio barrio;

	private PropiedadTipo propiedadTipo;

	private Integer cantDormitorios;

	private Integer cantToilette;

	private Integer cantCocinas;

	private Integer cantLiving;

	private Integer cantBanios;

	private Integer cantLocalComercial;

	private Boolean cochera;

	private String direccion;

	private Integer numero;

	private Integer piso;

	private String dpto;

	private Estado estado = Estado.D;

	private Integer montoMinimoAlquiler;

	private Integer montoMinimoVenta;

	private AlquilerVenta tipoDisponibilidad = AlquilerVenta.ALQUILER_VENTA;

	public Propiedad() {
		super();
	}

	public enum AlquilerVenta {
		ALQUILER("Alquiler"), VENTA("Venta"), ALQUILER_VENTA("Alquiler-Venta");

		private String rating;

		private AlquilerVenta(String rating) {
			this.rating = rating;
		}

		@Override
		public String toString() {
			return rating;
		}
	}

	public enum Estado {
		D("Disponible"), A("Alquilada"), V("Vendida");

		private String estado;

		private Estado(String estado) {
			this.estado = estado;
		}

		@Override
		public String toString() {
			return estado;
		}
	}

	@Embedded
	public Coordenada getCoordenada() {
		return coordenada;
	}

	public void setCoordenada(Coordenada coordenada) {
		this.coordenada = coordenada;
	}

	@Enumerated(EnumType.STRING)
	@NotNull(message = "{name.notnull}")
	public Estado getEstado() {
		return estado;
	}

	public void setEstado(Estado estado) {
		this.estado = estado;
	}

	@NotNull(message = "{name.notnull}")
	@ManyToOne(optional = false, fetch = FetchType.EAGER)
	@JoinColumn(name = "propietario_id", referencedColumnName = "id")
	public Propietario getPropietario() {
		return propietario;
	}

	public void setPropietario(Propietario propietario) {
		this.propietario = propietario;
	}

	@NotNull(message = "{name.notnull}")
	@ManyToOne(optional = false, fetch = FetchType.LAZY)
	@JoinColumn(name = "barrio_id", referencedColumnName = "id")
	public Barrio getBarrio() {
		return barrio;
	}

	public void setBarrio(Barrio barrio) {
		this.barrio = barrio;
	}

	@Column(name = "cant_dormitorios", nullable = false)
	@NotNull(message = "{name.notnull}")
	@Min(value = 0)
	@Max(value = 10)
	public Integer getCantDormitorios() {
		return cantDormitorios;
	}

	public void setCantDormitorios(Integer cantDormitorios) {
		this.cantDormitorios = cantDormitorios;
	}

	@Column(name = "direccion", nullable = false)
	@NotNull(message = "{name.notnull}")
	public String getDireccion() {
		return direccion;
	}

	public void setDireccion(String direccion) {
		this.direccion = direccion;
	}

	@NotNull(message = "{name.notnull}")
	@ManyToOne(optional = false, fetch = FetchType.EAGER)
	@JoinColumn(name = "propiedad_tipo_id", referencedColumnName = "id")
	public PropiedadTipo getPropiedadTipo() {
		return propiedadTipo;
	}

	public void setPropiedadTipo(PropiedadTipo propiedadTipo) {
		this.propiedadTipo = propiedadTipo;
	}

	// @NotNull(message = "{name.notnull}")
	public Integer getMontoMinimoAlquiler() {
		return montoMinimoAlquiler;
	}

	public void setMontoMinimoAlquiler(Integer montoMinimoAlquiler) {
		this.montoMinimoAlquiler = montoMinimoAlquiler;
	}

	// @NotNull(message = "{name.notnull}")
	public Integer getMontoMinimoVenta() {
		return montoMinimoVenta;
	}

	public void setMontoMinimoVenta(Integer montoMinimoVenta) {
		this.montoMinimoVenta = montoMinimoVenta;
	}

	@Enumerated(EnumType.STRING)
	@NotNull(message = "{name.notnull}")
	public AlquilerVenta getTipoDisponibilidad() {
		return tipoDisponibilidad;
	}

	public void setTipoDisponibilidad(AlquilerVenta tipoDisponibilidad) {
		this.tipoDisponibilidad = tipoDisponibilidad;
	}

	@NotNull(message = "{name.notnull}")
	@Min(value = 0)
	@Max(value = 4)
	public Integer getCantToilette() {
		return cantToilette;
	}

	public void setCantToilette(Integer cantToilette) {
		this.cantToilette = cantToilette;
	}

	@NotNull(message = "{name.notnull}")
	@Min(value = 0)
	@Max(value = 3)
	public Integer getCantCocinas() {
		return cantCocinas;
	}

	public void setCantCocinas(Integer cantCocinas) {
		this.cantCocinas = cantCocinas;
	}

	@NotNull(message = "{name.notnull}")
	@Min(value = 0)
	@Max(value = 4)
	public Integer getCantLiving() {
		return cantLiving;
	}

	public void setCantLiving(Integer cantLiving) {
		this.cantLiving = cantLiving;
	}

	@NotNull(message = "{name.notnull}")
	@Min(value = 0)
	@Max(value = 4)
	public Integer getCantBanios() {
		return cantBanios;
	}

	public void setCantBanios(Integer cantBanios) {
		this.cantBanios = cantBanios;
	}

	@NotNull(message = "{name.notnull}")
	public Boolean getCochera() {
		return cochera;
	}

	public void setCochera(Boolean cochera) {
		this.cochera = cochera;
	}

	@NotNull(message = "{name.notnull}")
	public Integer getNumero() {
		return numero;
	}

	public void setNumero(Integer numero) {
		this.numero = numero;
	}

	public Integer getPiso() {
		return piso;
	}

	public void setPiso(Integer piso) {
		this.piso = piso;
	}

	public String getDpto() {
		return dpto;
	}

	public void setDpto(String dpto) {
		this.dpto = dpto;
	}

	@NotNull(message = "{name.notnull}")
	@Min(value = 0)
	@Max(value = 10)
	public Integer getCantLocalComercial() {
		return cantLocalComercial;
	}

	public void setCantLocalComercial(Integer cantLocalComercial) {
		this.cantLocalComercial = cantLocalComercial;
	}

	public String direccionCompleta() {
		try {
			return getDireccion() + " Nro: " + getNumero()
					+ (getDpto() != null && !getDpto().equals("")? " Dto: " + getDpto() : "")
					+ (getPiso() != null && !getPiso().equals(0)? " Piso: " + getPiso() : "");
		} catch (Exception e) {
			return  getDireccion() + " Nro: " + getNumero();
		}
		
	}

	public Boolean disponible() {
		return getEstado().equals(Estado.D)
				&& !getTipoDisponibilidad().equals(AlquilerVenta.VENTA);
	}

	public boolean marcada() {
		if (this.getCoordenada() != null
				&& this.getCoordenada().getLat() != 0.0
				&& this.getCoordenada().getLng() != 0.0)
			return true;

		return false;
	}

}
